package db.newversion;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

import core.Constants;

public class GeneralDB {
	private static GeneralDB instance = null;
	private final String framework;
	private final String driver;
	private final String protocol;
	private final String dbName;
	private Connection connection;

	public static GeneralDB getInstance() {
		if (instance == null) {
			try {
				instance = new GeneralDB(Constants.ARCHER_DB);
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		return instance;
	}

	public static GeneralDB getInstance(String dbName) {
		if (instance == null) {
			try {
				instance = new GeneralDB(dbName);
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		return instance;
	}

	private GeneralDB(String dbName) throws SQLException {
		this.framework = Constants.FRAMEWORK;
		this.driver = Constants.DRIVER;
		this.protocol = Constants.PROTOCOL;
		this.dbName = dbName;

		this.loadDriver();
		this.connect();
	}

	private void loadDriver() {
		// load driver
		try {
			Class.forName(this.driver).newInstance();
			// System.out.println("Loaded the appropriate driver");
		} catch (ClassNotFoundException cnfe) {
			System.err.println("\nUnable to load the JDBC driver " + this.driver);
			System.err.println("Please check your CLASSPATH.");
			cnfe.printStackTrace(System.err);
		} catch (InstantiationException ie) {
			System.err.println("\nUnable to instantiate the JDBC driver " + this.driver);
			ie.printStackTrace(System.err);
		} catch (IllegalAccessException iae) {
			System.err.println("\nNot allowed to access the JDBC driver " + this.driver);
			iae.printStackTrace(System.err);
		}
	}

	private void connect() {
		try {
			this.connection = DriverManager.getConnection(this.protocol + this.dbName + ";create=true");
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}

	public void shudDown() {
		try {
			// the shutdown=true attribute shuts down Derby
			DriverManager.getConnection("jdbc:derby:;shutdown=true");

			// To shut down a specific database only, but keep the
			// engine running (for example for connecting to other
			// databases), specify a database in the connection URL:
			// DriverManager.getConnection("jdbc:derby:" + dbName +
			// ";shutdown=true");
		} catch (SQLException se) {
			if (((se.getErrorCode() == 50000) && ("XJ015".equals(se.getSQLState())))) {
				// we got the expected exception
				// System.out.println("Derby shut down normally");
				// Note that for single database shutdown, the expected
				// SQL state is "08006", and the error code is 45000.
			} else {
				// if the error code or SQLState is different, we have
				// an unexpected exception (shutdown failed)
				System.err.println("Derby did not shut down normally");
				System.err.println(se);
			}
		}
	}

	public void releasOpenRessources() {
		// Connection
		try {
			if (this.connection != null) {
				this.connection.close();
				this.connection = null;
			}
		} catch (SQLException sqle) {
			System.err.println(sqle);
		}
	}

	public Connection getConnection() {
		return this.connection;
	}
}
